-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
MDEV-37755 ilist::pop_back() removes sentinel #4411
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
|
fb09b6b to
5620ee3
Compare
dr-m
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work!
I would suggest some very minor cleanup to fil_space_free_low() and fil_space_t::drop().
storage/innobase/fil/fil0fil.cc
Outdated
| *detached_handle = handle; | ||
| else | ||
| os_file_close(handle); | ||
|
|
||
| /* The above mnt.commit_file() call should remove the space from | ||
| fil_system.named_spaces, but some pending operations can push it back | ||
| to the container again. */ | ||
| mysql_mutex_lock(&log_sys.mutex); | ||
| if (space->max_lsn != 0) | ||
| { | ||
| space->max_lsn= 0; | ||
| fil_system.named_spaces.remove(*space); | ||
| } | ||
| mysql_mutex_unlock(&log_sys.mutex); | ||
|
|
||
| return space; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that the added code corresponds to the logic in fil_space_free(). It could be good to mention that in a comment. I was also wondering if the code could be added right after the mysql_mutex_unlock(&fil_system.mutex), before we do anything with handle, to make it more like what fil_space_free() is doing.
As far as I understand, we should be able to safely simplify fil_space_free_low() as well:
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 4e8ddf5f757..08349905b86 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -861,13 +861,7 @@ static void fil_space_free_low(fil_space_t *space) noexcept
/* The tablespace must not be in fil_system.named_spaces. */
ut_ad(srv_fast_shutdown == 2 || !srv_was_started
|| space->max_lsn == 0);
-
- /* Wait for fil_space_t::release() after
- fil_system_t::detach(), the tablespace cannot be found, so
- fil_space_t::get() would return NULL */
- while (space->referenced()) {
- std::this_thread::sleep_for(std::chrono::microseconds(100));
- }
+ ut_ad(!space->referenced());
for (fil_node_t* node = UT_LIST_GET_FIRST(space->chain);
node != NULL; ) {
@@ -1604,15 +1598,12 @@ fil_space_t *fil_space_t::drop(ulint id, pfs_os_file_t *detached_handle)
pfs_os_file_t handle= fil_system.detach(space, true);
mysql_mutex_unlock(&fil_system.mutex);
- if (detached_handle)
- *detached_handle = handle;
- else
- os_file_close(handle);
-
- /* The above mnt.commit_file() call should remove the space from
- fil_system.named_spaces, but some pending operations can push it back
- to the container again. */
+ /* The above mtr.commit_file(*space, nullptr) should remove the space from
+ fil_system.named_spaces. Before we set the STOPPING_WRITES flag, another
+ concurrent operation could have marked the tablespace dirty again.
+ This clean-up corresponds to fil_space_free(). */
mysql_mutex_lock(&log_sys.mutex);
+ ut_ad((space->pending() & ~NEEDS_FSYNC) == (STOPPING | CLOSING));
if (space->max_lsn != 0)
{
space->max_lsn= 0;
@@ -1620,6 +1611,11 @@ fil_space_t *fil_space_t::drop(ulint id, pfs_os_file_t *detached_handle)
}
mysql_mutex_unlock(&log_sys.mutex);
+ if (detached_handle)
+ *detached_handle = handle;
+ else
+ os_file_close(handle);
+
return space;
}
I tested these changes on top of a merge of 5620ee3 to 759e352, and 200 runs of the test encryption.create_or_replace passed without incident, and so did a run of mysql-test/mtr --suite=encryption,innodb,mariabackup.
| if (fil_space_t *space= fil_space_t::drop(id, &handle)) | ||
| fil_space_free_low(space); | ||
| fil_space_free_low(space); | ||
| return handle; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The basic indentation offset should be 2 columns, not 4. This looks like an unintentional change that should be omitted.
5620ee3 to
5d528ba
Compare
…amed_spaces mtr.commit_file() call in fil_space_t::drop() removes space from fil_system.named_spaces, but then the space can be inserted in the container again by some another thread while fil_space_t::drop() is waiting for pending operations finishing. The fix is to check and remove a space from fil_system.named_spaces after all pengind operations on the space are finished. Also the ut_d() macro is removed for space->max_lsn=0 assignments to avoid repeated space removing from fil_system.named_spaces. There is error in ilist::pop_back(). ilist::end() returns sentinel, and the pop_back() removes sentinel from the list instead of the last element. The error is fixed in this commit. Reviewed by Marko Mäkelä
5d528ba to
7301fba
Compare
The fix is to remove previous to sentinel node instead of sentinel itself.
Description
TODO: fill description here
Release Notes
TODO: What should the release notes say about this change?
Include any changed system variables, status variables or behaviour. Optionally list any https://mariadb.com/kb/ pages that need changing.
How can this PR be tested?
TODO: modify the automated test suite to verify that the PR causes MariaDB to behave as intended.
Consult the documentation on "Writing good test cases".
If the changes are not amenable to automated testing, please explain why not and carefully describe how to test manually.
Basing the PR against the correct MariaDB version
mainbranch.PR quality check